<?php

namespace App\Admin\Controllers;

use App\Admin\Filters\WorshipPptFilter;
use App\Admin\Models\WorshipPpt;
use App\Admin\Requests\WorshipPptRequest;
use App\Admin\Resources\WorshipPptResource;
use App\Admin\Models\WorshipHymn;
use App\Admin\Models\WorshipBibleChapter;
use App\Admin\Models\WorshipBibleVolume;
use App\Admin\Models\SystemMedia;
use App\Admin\Models\SystemMediaCategory;
use App\Admin\Models\Config;
use App\Admin\Models\SystemModel;
use Cristal\Presentation\PPTX;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;

class WorshipPptController extends Controller
{
    // 每张经文页显示的章节数量
    public $lectionNumbers = 7;

    // 存储导出PPTX的分类名称
    public $pptxCate = '主日PPT';

    // 存储导出PPTX的目录
    public $pptxPath = 'uploads/';

    // 存储PPTX模版的目录
    public $pptxTemplatePath = 'pptx/template/';

    // 存储PPTX资源的目录
    public $pptxResourcePath = 'pptx/resource/';

    public function __construct(){
        $this->pptxTemplatePath .= Config::getConfigValue('export_template','hs169t').'/';
    }

    public function index(WorshipPptFilter $filter, WorshipPpt $worshipPpt)
    {
        $worshipPpts = WorshipPpt::withTrashed()
            ->filter($filter)
            ->select(SystemModel::getFields($worshipPpt->getTable()))
            ->orderBy('updated_at', 'desc')
            ->paginate();

        return $this->ok(WorshipPptResource::collection($worshipPpts));
    }

    public function create()
    {
        return $this->ok();
    }

    public function store(WorshipPptRequest $request, WorshipPpt $worshipPpt)
    {
        $inputs = $request->validated();
        $token = md5(json_encode($inputs));
        unset($inputs['token']);
        if (Cache::get($token) == 2) {
            return $this->error('请不要重复提交数据');
        } 
        Cache::put($token, 1);
        $worshipPpt = $worshipPpt->add($inputs);
        Cache::put($token, 2);

        return $this->created(WorshipPptResource::make($worshipPpt));
    }

    public function edit(Request $request, WorshipPpt $worshipPpt)
    {
        return $this->ok(WorshipPptResource::make($worshipPpt));
    }

    public function update(WorshipPptRequest $request, WorshipPpt $worshipPpt)
    {
        $inputs = $request->validated();
        $worshipPpt->update($inputs);

        return $this->created(WorshipPptResource::make($worshipPpt));
    }

    public function destroy(WorshipPpt $worshipPpt)
    {
        $worshipPpt->delete();
        return $this->noContent();
    }

    public function export(
        Request $request,
        WorshipPpt $worshipPpt,
        WorshipHymn $worshipHymn,
        WorshipBibleVolume $worshipBibleVolume,
        Int $id
    ){
        if (!file_exists($this->pptxResourcePath)) {
            mkdir($this->pptxResourcePath, 0777, true);
        } else {
            deldir($this->pptxResourcePath);
            mkdir($this->pptxResourcePath, 0777, true);
        }
        
        $worshipPptInfo = $worshipPpt->find($id)->toArray();    
        // head
        $headPPTX = new PPTX($this->pptxTemplatePath.'head.pptx');
        $worshipPptInfo['year'] = date('Y');
        $headPPTX->template(function ($matches) use ($worshipPptInfo) {
            return $worshipPptInfo[$matches['needle']] ?? null;
        });
        $headPPTX->saveAs($this->pptxResourcePath.'head.pptx');
      
        if ($worshipPptInfo['hymn_id']) {
            // hymn
            $worshipHymnInfo = $worshipHymn->find($worshipPptInfo['hymn_id']);
           
            if ($worshipHymnInfo) {
                $worshipHymnInfo = $worshipHymnInfo->toArray();  
                $worshipHymnContents = array_filter(explode("#", $worshipHymnInfo['content']));
                $worshipHymnContentCount = count($worshipHymnContents);
                $worshipHymnPPTX = new PPTX($this->pptxTemplatePath.'hymn.pptx');
                $worshipHymnPPTX->template(function ($matches) use ($worshipHymnInfo) {
                    return $worshipHymnInfo[$matches['needle']] ?? null;
                });
                $worshipHymnPPTX->saveAs($this->pptxResourcePath.'hymn.pptx');

                // hymn_*
                for ($i=0; $i < $worshipHymnContentCount; $i++) { 
                    $songPPTX = new PPTX($this->pptxTemplatePath.'hymn_song.pptx');
                    $worshipHymnInfo['content'] = explode("\n", $worshipHymnContents[$i]);
                    $content = [];
                    foreach ($worshipHymnInfo['content'] as $key => $value) {
                        $content['word'.$key] = $value;
                    }
                    // 渲染歌名
                    $content['name'] = $worshipHymnInfo['name'];
                    $songPPTX->template(function ($matches) use ($content) {
                        return $content[$matches['needle']] ?? null;
                    });
                    $songPPTX->saveAs($this->pptxResourcePath."/hymn_{$i}.pptx");
                }
            }
        }
        
        if ($worshipPptInfo['response_bible']) {
            // response_bible
            $responseBiblePPTX = new PPTX($this->pptxTemplatePath.'response_bible.pptx');
            $responseBiblePPTX->template(function ($responseBibleMatches) use ($worshipPptInfo) {
                return $worshipPptInfo[$responseBibleMatches['needle']] ?? null;
            });
            $responseBiblePPTX->saveAs($this->pptxResourcePath.'response_bible.pptx');

            // response_bible_*
            $responseBibleList = $worshipBibleVolume->lections($worshipPptInfo['response_bible']);
            $responseBibleCount = count($responseBibleList);
            $responseBiblePageInfo = getPage(1, $responseBibleCount, $this->lectionNumbers);
            for ($i=1; $i <= $responseBiblePageInfo['totalPages']; $i++) { 
                $cPageInfo = getPage($i, $responseBibleCount, $this->lectionNumbers);
                $cList = array_slice($responseBibleList, $cPageInfo['firstRow'], $cPageInfo['listRows']);
                $lectionPPTX = new PPTX($this->pptxTemplatePath.'lection.pptx');
                $lectionPPTX->template(function ($matches) use ($cList) {
                    $temp = [];
                    foreach ($cList as $key => $value) {
                        $temp['vcv'.$key] = $value['vcv'];
                        $temp['lection'.$key] = $value['lection'];
                    }
                    return $temp[$matches['needle']] ?? null;
                });
                $lectionPPTX->saveAs($this->pptxResourcePath."/response_bible_{$i}.pptx");
            }
        }
        
        if (!empty($worshipPptInfo['praise_id'])) {
            // praise_*
            $praiseInfo = $worshipHymn->whereIn('id', $worshipPptInfo['praise_id'])
                ->get([
                    'id',
                    'content',
                    'name',
                ]);
            if ($praiseInfo) {
                $praisePPTX = new PPTX($this->pptxTemplatePath.'praise.pptx');
                $praisePPTX->saveAs($this->pptxResourcePath.'praise.pptx');
                $praiseInfo = $praiseInfo->toArray();
                $praiseInfo = orderByArray(array_column($praiseInfo, null, 'id'), $worshipPptInfo['praise_id']);
                $praiseList = [];
                foreach ($praiseInfo as $key => $value) {
                    $praiseContents = array_filter(explode("#", $value['content']));
                    $praiseContentCount = count($praiseContents);
                    $content = [];
                    $content['name'] = $value['name'];
                    for ($i=0; $i < $praiseContentCount; $i++) { 
                        $value2 = explode("\n", $praiseContents[$i]);
                        foreach ($value2 as $key3 => $value3) {
                            $content['word'.$key3] = $value3;
                        }
                        array_push($praiseList, $content);
                    }
                }
                $praisePage = count($praiseList);
                for ($i=0; $i < $praisePage; $i++) { 
                    $songPPTX = new PPTX($this->pptxTemplatePath.'praise_song.pptx');
                    $content = $praiseList[$i];
                    $songPPTX->template(function ($matches) use ($content) {
                        return $content[$matches['needle']] ?? null;
                    });
                    $j = $i+1;
                    $songPPTX->saveAs($this->pptxResourcePath."/praise_{$j}.pptx");
                }
            }
        }

        if ($worshipPptInfo['choir_id']) {
            // choir
            $choirInfo = $worshipHymn->find($worshipPptInfo['choir_id'], [
                'id',
                'content',
                'name',
            ]);
            if ($choirInfo) {
                $choirInfo = $choirInfo->toArray();
                $choirContents = array_filter(explode("#", $choirInfo['content']));
                $choirContentCount = count($choirContents);
                $choirPPTX = new PPTX($this->pptxTemplatePath.'choir.pptx');
                $choirPPTX->template(function ($matches) use ($choirInfo) {
                    return $choirInfo[$matches['needle']] ?? null;
                });
                $choirPPTX->saveAs($this->pptxResourcePath.'choir.pptx');

                // choir_*
                for ($i=0; $i < $choirContentCount; $i++) { 
                    $songPPTX = new PPTX($this->pptxTemplatePath.'choir_song.pptx');
                    $choirInfo['content'] = explode("\n", $choirContents[$i]);
                    $content = [];
                    foreach ($choirInfo['content'] as $key => $value) {
                        $content['word'.$key] = $value;
                    }
                    // 渲染歌名
                    $content['name'] = $choirInfo['name'];
                    $songPPTX->template(function ($matches) use ($content) {
                        return $content[$matches['needle']] ?? null;
                    });
                    $songPPTX->saveAs($this->pptxResourcePath."/choir_{$i}.pptx");
                }
            }
        }        

        if ($worshipPptInfo['preach_title'] && $worshipPptInfo['preach_lection']) {
            // preach
            $preachPPTX = new PPTX($this->pptxTemplatePath.'preach.pptx');
            $preachPPTX->template(function ($matches) use ($worshipPptInfo) {
                return $worshipPptInfo[$matches['needle']] ?? null;
            });
            $preachPPTX->saveAs($this->pptxResourcePath.'preach.pptx');
            
            // preach_*
            $preachLectionList = $worshipBibleVolume->lections($worshipPptInfo['preach_lection']);
            $preachLectionCount = count($preachLectionList);
            $preachLectionPageInfo = getPage(1, $preachLectionCount, $this->lectionNumbers);
            for ($i=1; $i <= $preachLectionPageInfo['totalPages']; $i++) { 
                $cPageInfo = getPage($i, $preachLectionCount, $this->lectionNumbers);
                $cList = array_slice($preachLectionList, $cPageInfo['firstRow'], $cPageInfo['listRows']);
                $preachLectionInfo['vc'] = $worshipPptInfo['preach_lection'];
                $preachLectionInfo['lection'] = implode(array_column($cList, 'lection'));
                $lectionPPTX = new PPTX($this->pptxTemplatePath.'preach_lection.pptx');
                $lectionPPTX->template(function ($matches) use ($preachLectionInfo) {
                    return $preachLectionInfo[$matches['needle']] ?? null;
                });
                $lectionPPTX->saveAs($this->pptxResourcePath."/preach_{$i}.pptx");
            }
        }

        if ($worshipPptInfo['next_preach_title'] && $worshipPptInfo['next_preach_date'] 
            && $worshipPptInfo['next_preach_speaker'] 
            && $worshipPptInfo['next_preach_bible'] 
            ) {
            // preach_preview
            $worshipPptInfo['next_preach_date'] = date("m月d日", strtotime($worshipPptInfo['next_preach_date']));
            $preachPPTX = new PPTX($this->pptxTemplatePath.'preach_preview.pptx');
            $preachPPTX->template(function ($matches) use ($worshipPptInfo) {
                return $worshipPptInfo[$matches['needle']] ?? null;
            });
            $preachPPTX->saveAs($this->pptxResourcePath.'preach_preview.pptx');
        }
        

        // 合并PPTX
        $headPPTX = new PPTX($this->pptxResourcePath.'head.pptx');

        $hymnPPTXName = $this->pptxResourcePath.'hymn.pptx';
        if (file_exists($hymnPPTXName)) {
            $worshipHymnPPTX = new PPTX($hymnPPTXName);
            $headPPTX->addSlides($worshipHymnPPTX->getSlides());
            for ($i=0; $i < $worshipHymnContentCount; $i++) { 
                $pptx = new PPTX($this->pptxResourcePath."/hymn_{$i}.pptx");
                $headPPTX->addSlides($pptx->getSlides());
            }
        }
        
        $responseBiblePPTXName = $this->pptxResourcePath.'response_bible.pptx';
        if (file_exists($responseBiblePPTXName)) {
            $responseBiblePPTX = new PPTX($responseBiblePPTXName);
            $headPPTX->addSlides($responseBiblePPTX->getSlides());
            for ($i=1; $i <= $responseBiblePageInfo['totalPages']; $i++) { 
                $pptx = new PPTX($this->pptxResourcePath."/response_bible_{$i}.pptx");
                $headPPTX->addSlides($pptx->getSlides());
            } 
        }
        
        $praisePPTXName = $this->pptxResourcePath.'praise.pptx';
        if (file_exists($praisePPTXName)) {
            $praisePPTX = new PPTX($praisePPTXName);
            $headPPTX->addSlides($praisePPTX->getSlides());
            for ($i=1; $i <= $praisePage; $i++) { 
                $pptx = new PPTX($this->pptxResourcePath."/praise_{$i}.pptx");
                $headPPTX->addSlides($pptx->getSlides());
            }  
        }
        
        $choirPPTXName = $this->pptxResourcePath.'choir.pptx';
        if (file_exists($choirPPTXName)) {
            $choirPPTX = new PPTX($choirPPTXName);
            $headPPTX->addSlides($choirPPTX->getSlides());
            for ($i=0; $i < $choirContentCount; $i++) { 
                $pptx = new PPTX($this->pptxResourcePath."/choir_{$i}.pptx");
                $headPPTX->addSlides($pptx->getSlides());
            }    
        }

        $preachPPTXName = $this->pptxResourcePath.'preach.pptx';
        if (file_exists($preachPPTXName)) {
            $preachPPTX = new PPTX($preachPPTXName);
            $headPPTX->addSlides($preachPPTX->getSlides());
            for ($i=1; $i <= $preachLectionPageInfo['totalPages']; $i++) { 
                $pptx = new PPTX($this->pptxResourcePath."/preach_{$i}.pptx");
                $headPPTX->addSlides($pptx->getSlides());
            }     
        }
        
        $eucharistPPTXName = $this->pptxTemplatePath.'eucharist.pptx';
        if (file_exists($eucharistPPTXName)) {
            $eucharistPPTX = new PPTX($eucharistPPTXName);
            $headPPTX->addSlides($eucharistPPTX->getSlides());
        }

        $prayerPPTXName = $this->pptxTemplatePath.'prayer.pptx';
        if (file_exists($prayerPPTXName)) {
            $prayerPPTX = new PPTX($prayerPPTXName);
            $headPPTX->addSlides($prayerPPTX->getSlides());
        }
        
        $newFriendPPTXName = $this->pptxTemplatePath.'new_friend.pptx';
        if (file_exists($newFriendPPTXName)) {
            $newFriendPPTX = new PPTX($newFriendPPTXName);
            $headPPTX->addSlides($newFriendPPTX->getSlides());
        }

        $familyReportPPTXName = $this->pptxTemplatePath.'family_report.pptx';
        if (file_exists($familyReportPPTXName)) {
            $familyReportPPTX = new PPTX($familyReportPPTXName);
            $headPPTX->addSlides($familyReportPPTX->getSlides());
        }

        $preachPreviewPPTXName = $this->pptxResourcePath.'preach_preview.pptx';
        if (file_exists($preachPreviewPPTXName)) {
            $preachPreviewPPTX = new PPTX($preachPreviewPPTXName);
            $headPPTX->addSlides($preachPreviewPPTX->getSlides());
        }

        $tailPPTXName = $this->pptxTemplatePath.'tail.pptx';
        if (file_exists($tailPPTXName)) {
            $tailPPTX = new PPTX($tailPPTXName);
            $headPPTX->addSlides($tailPPTX->getSlides());
        }
       
        // PPTX文件名称
        $pptxName = 'worship-'.$worshipPptInfo['worship_date'].'.pptx';
        $path = $this->pptxPath.$pptxName;
        $headPPTX->saveAs($path);
        $pptxUrl = config()->get('app.url').'/'.$path;
        // 存储到数据库
        DB::beginTransaction();
        // 更新或创建文件分类
        $cateData['name'] = $this->pptxCate;;
        $cateData['parent_id'] = 0;
        $cate = SystemMediaCategory::updateOrCreate($cateData);
        // 获取文件信息
        $file = UploadedFile::fake()->image($path);
        // 存储文件信息
        $mediaData['origin_filename'] = $pptxName;
        $mediaData['filename'] = md5_file($file);
        $mediaData['ext'] = 'pptx';
        $mediaData['category_id'] = $cate->id;
        $mediaData['path'] = '/'.$path;
        $mediaData['path_key'] = md5($path);
        $mediaData['size'] = $file->getSize();
        $mediaData['mime_type'] = $file->getMimeType();
        $media = SystemMedia::create($mediaData);
        if ($cate && $media) {
            DB::commit();
        } else {
            DB::rollBack();
        }
        return $this->ok(['pptx_url'=>$pptxUrl]);
    }

    public function show(Request $request, Int $id)
    {
        $worshipPpt = WorshipPpt::withTrashed()
            ->select(SystemModel::getFields(app(WorshipPpt::class)->getTable(), 'detail'))
            ->find($id);
        return $this->ok(WorshipPptResource::make($worshipPpt));
    }
}
